﻿#include "conversionutil.h"


quint8 ConversionUtil::ByteArrayToU1(QByteArray array)
{
    Q_ASSERT(!array.isEmpty());
    return static_cast<quint8>(array.at(0));
}

quint16 ConversionUtil::ByteArrayToU2(QByteArray array)
{
    Q_ASSERT(array.size() >= 2);
    return (static_cast<quint8>(array.at(0)) << 8) |
           static_cast<quint8>(array.at(1));
}

quint32 ConversionUtil::ByteArrayToU4(QByteArray array)
{
    Q_ASSERT(array.size() >= 4);
    return (static_cast<quint8>(array.at(0)) << 24) |
           (static_cast<quint8>(array.at(1)) << 16) |
           (static_cast<quint8>(array.at(2)) << 8)  |
           static_cast<quint8>(array.at(3));
}

quint64 ConversionUtil::ByteArrayToU8(QByteArray array)
{
    Q_ASSERT(array.size() >= 8);
    return (static_cast<quint64>(static_cast<quint8>(array.at(0))) << 56) |
           (static_cast<quint64>(static_cast<quint8>(array.at(1))) << 48) |
           (static_cast<quint64>(static_cast<quint8>(array.at(2))) << 40) |
           (static_cast<quint64>(static_cast<quint8>(array.at(3))) << 32) |
           (static_cast<quint64>(static_cast<quint8>(array.at(4))) << 24) |
           (static_cast<quint64>(static_cast<quint8>(array.at(5))) << 16) |
           (static_cast<quint64>(static_cast<quint8>(array.at(6))) << 8)  |
           static_cast<quint64>(static_cast<quint8>(array.at(7)));
}

qint8 ConversionUtil::ByteArrayToI1(QByteArray array)
{
    Q_ASSERT(!array.isEmpty());
    return static_cast<qint8>(array.at(0));
}

qint16 ConversionUtil::ByteArrayToI2(QByteArray array)
{
    Q_ASSERT(array.size() >= 2);
    return (static_cast<qint8>(array.at(0)) << 8) |
           static_cast<qint8>(array.at(1));
}

qint32 ConversionUtil::ByteArrayToI4(QByteArray array)
{
    Q_ASSERT(array.size() >= 4);
    return (static_cast<quint8>(array.at(0)) << 24) |
           (static_cast<quint8>(array.at(1)) << 16) |
           (static_cast<quint8>(array.at(2)) << 8)  |
           static_cast<quint8>(array.at(3));
}

qint64 ConversionUtil::ByteArrayToI8(QByteArray array)
{
    Q_ASSERT(array.size() >= 8);
    return (static_cast<qint64>(static_cast<quint8>(array.at(0))) << 56) |
           (static_cast<qint64>(static_cast<quint8>(array.at(1))) << 48) |
           (static_cast<qint64>(static_cast<quint8>(array.at(2))) << 40) |
           (static_cast<qint64>(static_cast<quint8>(array.at(3))) << 32) |
           (static_cast<qint64>(static_cast<quint8>(array.at(4))) << 24) |
           (static_cast<qint64>(static_cast<quint8>(array.at(5))) << 16) |
           (static_cast<qint64>(static_cast<quint8>(array.at(6))) << 8)  |
           static_cast<qint64>(static_cast<quint8>(array.at(7)));
}

float ConversionUtil::ByteArrayToF4(QByteArray array)
{
    float number;
    Q_ASSERT(array.size() == sizeof(number));
    std::memcpy(&number, array.data(), sizeof(number));
    return number;
}

double ConversionUtil::ByteArrayToF8(QByteArray array)
{
    double number;
    Q_ASSERT(array.size() == sizeof(number));
    std::memcpy(&number, array.data(), sizeof(number));
    return number;
}

char ConversionUtil::ByteArrayToChar(QByteArray array)
{
    return array.at(0);
}

QString ConversionUtil::ByteArrayToASCII(QByteArray array)
{
    return QString::fromUtf8(array);
}

bool ConversionUtil::ByteArrayToBoolean(QByteArray array)
{
    return !array.isEmpty() && (array.toLower() == "true" || array.toInt() != 0);
}

std::vector<quint8> ConversionUtil::ByteArrayToU1List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(quint8) == 0);
    std::vector<quint8> list;

    for (int i = 0; i <= array.size() - sizeof(quint8); i += sizeof(quint8))
    {
        list.push_back(ByteArrayToU1(array.mid(i, sizeof(quint8))));
    }

    return list;
}

std::vector<quint16> ConversionUtil::ByteArrayToU2List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(quint16) == 0);
    std::vector<quint16> list;

    for (int i = 0; i <= array.size() - sizeof(quint16); i += sizeof(quint16))
    {
        list.push_back(ByteArrayToU2(array.mid(i, sizeof(quint16))));
    }

    return list;
}

std::vector<quint32> ConversionUtil::ByteArrayToU4List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(quint32) == 0);
    std::vector<quint32> list;

    for (int i = 0; i <= array.size() - sizeof(quint32); i += sizeof(quint32))
    {
        list.push_back(ByteArrayToU4(array.mid(i, sizeof(quint32))));
    }

    return list;
}

std::vector<quint64> ConversionUtil::ByteArrayToU8List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(quint64) == 0);
    std::vector<quint64> list;

    for (int i = 0; i <= array.size() - sizeof(quint64); i += sizeof(quint64))
    {
        list.push_back(ByteArrayToU8(array.mid(i, sizeof(quint64))));
    }

    return list;
}

std::vector<qint8> ConversionUtil::ByteArrayToI1List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(qint8) == 0);
    std::vector<qint8> list;

    for (int i = 0; i <= array.size() - sizeof(qint8); i += sizeof(qint8))
    {
        list.push_back(ByteArrayToI1(array.mid(i, sizeof(qint8))));
    }

    return list;
}

std::vector<qint16> ConversionUtil::ByteArrayToI2List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(qint16) == 0);
    std::vector<qint16> list;

    for (int i = 0; i <= array.size() - sizeof(qint16); i += sizeof(qint16))
    {
        list.push_back(ByteArrayToI2(array.mid(i, sizeof(qint16))));
    }

    return list;
}

std::vector<qint32> ConversionUtil::ByteArrayToI4List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(qint32) == 0);
    std::vector<qint32> list;

    for (int i = 0; i <= array.size() - sizeof(qint32); i += sizeof(qint32))
    {
        list.push_back(ByteArrayToI4(array.mid(i, sizeof(qint32))));
    }

    return list;
}

std::vector<qint64> ConversionUtil::ByteArrayToI8List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(qint64) == 0);
    std::vector<qint64> list;

    for (int i = 0; i <= array.size() - sizeof(qint64); i += sizeof(qint64))
    {
        list.push_back(ByteArrayToI8(array.mid(i, sizeof(qint64))));
    }

    return list;
}

std::vector<float> ConversionUtil::ByteArrayToF4List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(float) == 0);
    std::vector<float> list;

    for (int i = 0; i <= array.size() - sizeof(float); i += sizeof(float))
    {
        list.push_back(ByteArrayToF4(array.mid(i, sizeof(float))));
    }

    return list;
}

std::vector<double> ConversionUtil::ByteArrayToF8List(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(double) == 0);
    std::vector<double> list;

    for (int i = 0; i <= array.size() - sizeof(double); i += sizeof(double))
    {
        list.push_back(ByteArrayToF8(array.mid(i, sizeof(double))));
    }

    return list;
}

std::vector<char> ConversionUtil::ByteArrayToCharList(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(char) == 0);
    std::vector<char> list;

    for (int i = 0; i <= array.size() - sizeof(char); i += sizeof(char))
    {
        list.push_back(ByteArrayToChar(array.mid(i, sizeof(char))));
    }

    return list;
}

std::vector<bool> ConversionUtil::ByteArrayToBoolList(QByteArray array)
{
    Q_ASSERT(array.size() % sizeof(bool) == 0);
    std::vector<bool> list;

    for (int i = 0; i <= array.size() - sizeof(bool); i += sizeof(bool))
    {
        list.push_back(ByteArrayToBoolean(array.mid(i, sizeof(bool))));
    }

    return list;
}

QByteArray ConversionUtil::U1ToByteArray(quint8 value)
{
    QByteArray array;
    array.append(static_cast<char>(value));
    return array;
}

QByteArray ConversionUtil::U2ToByteArray(quint16 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::U4ToByteArray(quint32 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 24) & 0xFF));
    array.append(static_cast<char>((value >> 16) & 0xFF));
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::U8ToByteArray(quint64 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 56) & 0xFF));
    array.append(static_cast<char>((value >> 48) & 0xFF));
    array.append(static_cast<char>((value >> 40) & 0xFF));
    array.append(static_cast<char>((value >> 32) & 0xFF));
    array.append(static_cast<char>((value >> 24) & 0xFF));
    array.append(static_cast<char>((value >> 16) & 0xFF));
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::I1ToByteArray(qint8 value)
{
    QByteArray array;
    array.append(static_cast<char>(value));
    return array;
}

QByteArray ConversionUtil::I2ToByteArray(qint16 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::I4ToByteArray(qint32 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 24) & 0xFF));
    array.append(static_cast<char>((value >> 16) & 0xFF));
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::I8ToByteArray(qint64 value)
{
    QByteArray array;
    array.append(static_cast<char>((value >> 56) & 0xFF));
    array.append(static_cast<char>((value >> 48) & 0xFF));
    array.append(static_cast<char>((value >> 40) & 0xFF));
    array.append(static_cast<char>((value >> 32) & 0xFF));
    array.append(static_cast<char>((value >> 24) & 0xFF));
    array.append(static_cast<char>((value >> 16) & 0xFF));
    array.append(static_cast<char>((value >> 8) & 0xFF));
    array.append(static_cast<char>(value & 0xFF));
    return array;
}

QByteArray ConversionUtil::F4ToByteArray(float value)
{
    QByteArray array;
    array.resize(sizeof(value));
    std::memcpy(array.data(), &value, sizeof(value));
    return array;
}

QByteArray ConversionUtil::F8ToByteArray(double value)
{
    QByteArray array;
    array.resize(sizeof(value));
    std::memcpy(array.data(), &value, sizeof(value));
    return array;
}

QByteArray ConversionUtil::CharToByteArray(char value)
{
    QByteArray array;
    array.append(value);
    return array;
}

QByteArray ConversionUtil::QStringToByteArray(QString value)
{
    return value.toUtf8();
}

QByteArray ConversionUtil::BoolToByteArray(bool value)
{
    QByteArray array;
    array.append(value ? '\x01' : '\x00');
    return array;
}

QByteArray ConversionUtil::U1ListToByteArray(std::vector<quint8> list)
{
    QByteArray array;

    for(quint8 value : list)
    {
        array.append(U1ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::U2ListToByteArray(std::vector<quint16> list)
{
    QByteArray array;

    for(quint16 value : list)
    {
        array.append(U2ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::U4ListToByteArray(std::vector<quint32> list)
{
    QByteArray array;

    for(quint32 value : list)
    {
        array.append(U4ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::U8ListToByteArray(std::vector<quint64> list)
{
    QByteArray array;

    for(quint64 value : list)
    {
        array.append(U8ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::I1ListToByteArray(std::vector<qint8> list)
{
    QByteArray array;

    for(qint8 value : list)
    {
        array.append(I1ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::I2ListToByteArray(std::vector<qint16> list)
{
    QByteArray array;

    for(qint16 value : list)
    {
        array.append(I2ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::I4ListToByteArray(std::vector<qint32> list)
{
    QByteArray array;

    for(qint32 value : list)
    {
        array.append(I4ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::I8ListToByteArray(std::vector<qint64> list)
{
    QByteArray array;

    for(qint64 value : list)
    {
        array.append(I8ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::F4ListToByteArray(std::vector<float> list)
{
    QByteArray array;

    for(float value : list)
    {
        array.append(F4ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::F8ListToByteArray(std::vector<double> list)
{
    QByteArray array;

    for(double value : list)
    {
        array.append(F8ToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::CharListToByteArray(std::vector<char> list)
{
    QByteArray array;

    for(char value : list)
    {
        array.append(CharToByteArray(value));
    }

    return array;
}

QByteArray ConversionUtil::BoolListToByteArray(std::vector<bool> list)
{
    QByteArray array;

    for(bool value : list)
    {
        array.append(BoolToByteArray(value));
    }

    return array;
}
